﻿#include "overallsituation.h"


FileOperation config;
LinuxSystemMethod sys;
int SerialPort;//选中端口
QTcpSocket *ClientSocket;
//QString ServerAddress;
//QString ServerPor;
QString currentPath="";
quint16 Prot;
int Playposition=0;
//QString URL="";
//QString Sockettime="";

// QString PortNum="";
// QString DeleteFiles="";
// QString TheLocalKey="";
// QString TheLocalKeyPDW="";
// QString Ttime="";
// QString BackgroundVersion="";
// QString UploadUrl="";
// QString MountUrl="";
// QString Mode="";
// QString MemoryLack="";
// QString CPULack="";
// QString Camera="";
// QString FingerPrint="";
// QString FaceRecognition="";
// QString prior="";
// QString Name="";
// QString Version="";
// QString Model="";
// QString Date="";
// QString Icon="";
// QString DesktopIcon="";
//  QString BVersion="";//后台版本号
  QString UploadRate="";//最大上传速率
//  QString System="";//系统
////QString text="";
//QString MUI="";
//QString CPU="";
//QString MEMORY="";
//QString DISK="";
//QString NETWORK="";

 QString authorize_code="";//当前授权码
  QString CallPoliceInfo="";
QString mac="";
QString time_on="";
QString time_end="";
QString NetworkName="";
QString IP="";
QString NewUserID="";//当前登录用户ID
//QString Notice="";
//QMutex myVecMutex;
//QMutex DeviceserialMutex;
//QMutex DriveLetterMutex;
 bool Isbinding[SYSTEMSUM];//是否绑定 true为已经重置成功，false反正
bool IsPriorlize[SYSTEMSUM];//是否为优先口 true为优先口，false反正
bool IsInitalize[SYSTEMSUM];//是否初始化 true为已经初始化成功，false反正
bool IsALLlist[SYSTEMSUM];//是否重置路径 true为已经重置成功，false反正
bool IsExtract[SYSTEMSUM];//是否拔出 true为已经重置成功，false反正
bool IsUpload[SYSTEMSUM];//是否上传 true为已经重置成功，false反正
int  IsBackdll[SYSTEMSUM];//dll调用是否成功 0进入转盘 1转盘成功 -1转盘失败 2磁盘模式 3正在传盘
QString TemporaryPath[SYSTEMSUM];//临时路径
qint64 IdentElectricity[SYSTEMSUM];
qint64 IsDriverTime[SYSTEMSUM];//等待磁盘时间

QString cSerial[SYSTEMSUM];         //执法记录仪产品序号
QString userNo[SYSTEMSUM];      //执法记录仪警员编号
QString userName[SYSTEMSUM]; //执法记录仪警员名称
QString unitNo[SYSTEMSUM];       //执法记录仪单位编号
QString unitName[SYSTEMSUM];  //执法记录仪单位名称
QString status[SYSTEMSUM];   //执法仪禁用状态
QString bindStatus[SYSTEMSUM];//执法仪配对状态；
QString watermark[SYSTEMSUM];//水印；
QString resolution[SYSTEMSUM];//分辨率；

//迁移
DeviceInforMation deviceinfo;
int NewSerialportNum;//现在选择的是几号重置口
int AppointFirstNum;//现在选择的是几号优先串口
bool IsClosingLogin;//是否关闭登录窗体
bool IsAppointFirst;//是否指定优先
bool IsWarnInstance;//是否是警情模式
 bool IsDeleteFiles;//上传是否删除文件
  bool IsCallPolice=true;
int AppointFirst;//优先串口
int row;//行
int column;//列
int Newrow;//行
int Newcolumn;//列
int StayScreen;//停留界面
int NewUserStatus;//当前登录用户身份 0普通用户 1管理用户
int CPUAbnormalNum=0;
double FreeGB;
QString IdentModel[SYSTEMSUM];//记录设备型号
QString IdentNumber[SYSTEMSUM];//记录设备标识号
QString IsUdisk[SYSTEMSUM];//转盘是否成功 有值则有，没有则无
std::vector<Announcement> Notice;

std::vector<QString> newDrives;//盘符号
std::vector<UsbInfo> usbInfo;//接入的设备信息
std::vector<DepartmentInfo>Filetype ;//文件类型
std::vector<DepartmentInfo>DepartmentName ;//部门名称
std::vector<WarnInfo>PoliceInfo ;//警情名称
 std::list<BindingInfo>BindList;
OverAllSituation::OverAllSituation()
{

}


void xorEncryptDecrypt(QByteArray& data, const QString& key) {
    // Convert the key to a QByteArray
    QByteArray keyData = key.toUtf8();
    // Perform the XOR operation with the key bytes
    data[0] = data[0] - keyData.at(0);
    data[1] = data[1] - keyData.at(1);
    data[2] = data[2] - keyData.at(2);
    data[3] = data[3] - keyData.at(3);
    data[4] = data[4] - keyData.at(4);
    data[5] = data[5] - keyData.at(5);
}
void xorEncryptDecrypt2(QByteArray& data, const QString& key) {
    // Convert the key to a QByteArray
    QByteArray keyData = key.toUtf8();

    // Perform the XOR operation with the key bytes
    data[0] = data[0] + keyData.at(0);
    data[1] = data[1] + keyData.at(1);
    data[2] = data[2] + keyData.at(2);
    data[3] = data[3] + keyData.at(3);
    data[4] = data[4] + keyData.at(4);
    data[5] = data[5] + keyData.at(5);
}

bool encryptFile(const QString& filePath, const QString& password) {
    QFile inputFile(filePath);
    if (!inputFile.open(QIODevice::ReadWrite)) {
        qDebug() << "Failed to open the file for encryption!";
        return false;
    }

    QByteArray fileData = inputFile.readAll();
    xorEncryptDecrypt(fileData, password);

    // Move to the beginning of the file to overwrite its content with the encrypted data
    inputFile.seek(0);
    inputFile.write(fileData);
    inputFile.close();

    qDebug() << "File encrypted successfully!";
    return true;
}

bool decryptFile(const QString& filePath, const QString& password) {
    QFile inputFile(filePath);
    if (!inputFile.open(QIODevice::ReadWrite)) {
        qDebug() << "Failed to open the file for decryption!";
        return false;
    }

    QByteArray fileData = inputFile.readAll();
    xorEncryptDecrypt2(fileData, password);

    // Move to the beginning of the file to overwrite its content with the decrypted data
    inputFile.seek(0);
    inputFile.write(fileData);
    inputFile.close();

    qDebug() << "File decrypted successfully!";
    return true;
}



//void xorEncryptDecrypt(vector<char>& data, const string& key) {
//    for (size_t i = 0; i < data.size(); ++i) {
//        // Perform the XOR operation with the key bytes
//        data[i] = data[i] ^ key[i % key.size()];
//    }
//}

//void encryptFile(const string& filePath, const string& password) {
//    ifstream inputFile(filePath, ios::binary);
//    if (!inputFile) {
//        cout << "Failed to open the file for encryption!" << endl;
//        return;
//    }

//    vector<char> fileData((istreambuf_iterator<char>(inputFile)), (istreambuf_iterator<char>()));
//    xorEncryptDecrypt(fileData, password);

//    inputFile.close();

//    ofstream outputFile(filePath, ios::binary);
//    if (!outputFile) {
//        cout << "Failed to write encrypted data to file!" << endl;
//        return;
//    }

//    outputFile.write(fileData.data(), fileData.size());
//    outputFile.close();

//    cout << "File encrypted successfully!" << endl;
//}

//void decryptFile(const string& filePath, const string& password) {
//    ifstream inputFile(filePath, ios::binary);
//    if (!inputFile) {
//        cout << "Failed to open the file for decryption!" << endl;
//        return;
//    }

//    vector<char> encryptedData((istreambuf_iterator<char>(inputFile)), (istreambuf_iterator<char>()));
//    xorEncryptDecrypt(encryptedData, password);

//    inputFile.close();

//    ofstream outputFile(filePath, ios::binary);
//    if (!outputFile) {
//        cout << "Failed to write decrypted data to file!" << endl;
//        return;
//    }

//    outputFile.write(encryptedData.data(), encryptedData.size());
//    outputFile.close();

//    cout << "File decrypted successfully!" << endl;
//}


//inline void DeviceInfo()
//{
//    deviceinfo.vid= "";//vid
//    deviceinfo.pid= "";//pid
//    deviceinfo.serialnumber= "";//设备序列号
//    deviceinfo.manufacturer= "";//设备制造商 3
//    deviceinfo.model= "";//设备型号 4
//    deviceinfo.route= "";//位置路径
//    deviceinfo.serialportnum= 0;//几号串口
//    deviceinfo.Device= "";// 是否为优先
//}
void getUsbInfo()
{
    usbInfo.clear();
    // 创建一个QProcess对象
    QProcess process;

    // 设置要执行的命令
    process.start("lsusb");

    // 等待进程完成
    process.waitForFinished();

    // 读取命令输出
    QByteArray output = process.readAllStandardOutput();


    // 将输出转换为字符串并按行分割
    QList<QByteArray> lines = output.split('\n');

    // 定义正则表达式用于匹配输出行
    QRegularExpression regex("Bus (\\d+) Device (\\d+): ID (\\S+) (.+)");

    // 解析每行输出
    foreach (const QByteArray &line, lines) {
        // 进行正则表达式匹配
        QRegularExpressionMatch match = regex.match(line);

        // 如果匹配成功，提取Bus值、Device值、ID值和设备名称
        if (match.hasMatch()) {
            int bus = match.captured(1).toInt();
            int device = match.captured(2).toInt();
            QString id = match.captured(3);
            QString deviceName = match.captured(4);


            // 拆分ID值
            QStringList idParts = id.split(':');
            if (idParts.size() == 2) {
                QString vendorId = idParts[0];
                QString productId = idParts[1];

                UsbInfo Info;
                Info.Bus=QString("%1-%2").arg(bus).arg(device);
                Info.vid=vendorId;
                Info.pid=productId;
                Info.deviceName=deviceName;
                usbInfo.push_back(Info);


                // 输出提取的值
                qDebug() << "Bus:" << Info.Bus <<"ID:" << vendorId<<"pid"<<productId<<"deviceName"<<deviceName;

            }
        }
    }


}
void InterfaceMapInfo()
{
    QString value="";
    QString Drive="";
    getUsbInfo();
    //获取初始化
    for (int r = 1; r <= row; r++) {
        for (int col = 1; col <= column; col++) {
            int number = (r - 1) * 5 + col;  // 计算当前格子的数字
            IsInitalize[number]=true;//设置为已经初始化
            emit GlobalSignals::instance().SetLabel(number,""," ","未初始化",1);
            emit GlobalSignals::instance().SetLabel(number+100,""," ","",1);
        }
    }
    //对所有串口检验
    for(int q=1;q<=(SYSTEMROW*SYSTEMLIST);q++)
    {
        // deviceinfo.serialportnum=q;
        /*例2、获取界面中的名字叫label的QLabel*/
        if(config.ReadRouteInfo("config_route.ini",QString("Initalize_%1").arg(q),value))//已经获取的路径文件
        {
            IsALLlist[q]=true;//是否重置路径
            // DeviceInfo();
            emit GlobalSignals::instance().SetLabel(q,"","","已初始化",1);
            emit GlobalSignals::instance().SetLabel(q+100,"","","空闲",1);

            //上一次转盘成功未拔出来的设备
            if(config.ReadRouteInfo("config_record.ini",QString("label_%1").arg(q),Drive))//已经获取的路径文件
            {
                if(Drive!="")
                {
//                    int colonIndex = Drive.indexOf(":"); // 查找冒号的索引位置
//                    QString result = Drive.mid(colonIndex + 1); // 使用mid()函数截取冒号后面的子串
//                    int commaIndex = result.indexOf(","); // 查找逗号的索引位置
//                    QString beforeComma = result.left(commaIndex); // 截取逗号之前的字符
//                    QString afterComma = result.mid(commaIndex + 1); // 截取逗号之后的字符
  QString beforeComma=Drive.section(';',0,0);
QString serialnumber=Drive.section(';',1,1);
QString afterComma=Drive.section(';',2,2);
QString Bus=Drive.section(';',3,3);


qDebug() << serialnumber<<"serialnumber";
qDebug() << Bus<<"Bus";
                    // 输出截取的子串
                    qDebug() << beforeComma<<"beforeComma";
                    qDebug() << afterComma<<"afterComma";


                    auto it = std::find_if(usbInfo.begin(), usbInfo.end(), [&](const UsbInfo Info) {
                        qDebug() <<Info.Bus<<Bus;
                        return (Info.Bus==Bus);
                    });

                    // If the target element is found, erase itvid from the vector
                    if (it != usbInfo.end()) {

                        // 输出提取的值
                        qDebug() <<"存在"<<it->Bus;
                        if (sys.getPathSpace(beforeComma)&&beforeComma!="")
                        {
                            QString Drice="";
                            if(config.ReadRouteInfo(QString("%1/ZFYConfig.ini").arg(beforeComma),"PID",Drice))
                            {
                                if(Drice==afterComma)
                                {
                                    IsUdisk[q]=beforeComma;
                                    IdentNumber[q]=afterComma;
                                     //emit GlobalSignals::instance().SetLabel(q+100,"",QString("产品序号"+":%1\n"+"用户编号"+":\n"+"用户名称"+":\n"+"单位名称"+":").arg(afterComma),"磁盘模式",1);
                                    emit GlobalSignals::instance().SetLabel(q+100,"",QString("产品序号:%1\n用户编号:\n用户名称:\n单位名称:").arg(afterComma),"磁盘模式",1);
                                }

                            }


                        }
                    }
                    else
                    {

                    }


                }

            }
        }
    }
}
//获取新的盘符
void CheckDriveChanges()
{
    newDrives.clear();
    QDir dir("/");
    QFileInfoList drives = dir.drives();
    for (const QFileInfo& drive : drives)
    {
        int colonIndex = drive.absoluteFilePath().indexOf(":"); // 查找冒号的索引位置
        newDrives.push_back(drive.absoluteFilePath().left(colonIndex));
        config.WriteInfo(QString("最新的所有盘符:%1").arg(drive.absoluteFilePath().left(colonIndex)));
    }

}

GlobalSignals::GlobalSignals()
{

}
//加密 cbc pkcs5padding 本身实现  //pkcs7padding 跟 pkcs5padding是同样的
std::string des_cbc_pkcs5_encrypt(const std::string &clearText)
{
    static unsigned char cbc_iv[8] = {'p', 'a', 's', 's', 'w', 'o', 'r', 'd'};
    //初始化IV向量【我这边密码与IV相同】
    std::string strCipherText;
    DES_cblock keyEncrypt, ivec;

    memcpy(keyEncrypt, cbc_iv, sizeof(cbc_iv));

    DES_key_schedule keySchedule;  //密钥表
    DES_set_key_unchecked(&keyEncrypt, &keySchedule);   //设置密钥，且不检测密钥奇偶性

    memcpy(ivec, cbc_iv, sizeof(cbc_iv));

    // 循环加密，每8字节一次
    const_DES_cblock inputText;
    DES_cblock outputText;
    std::vector<unsigned char> vecCiphertext;
    unsigned char tmp[8];

    for (int i = 0; i < clearText.length() / 8; i++)
    {
        memcpy(inputText, clearText.c_str() + i * 8, 8);
        DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_ENCRYPT);  //加密
        memcpy(tmp, outputText, 8);

        for (int j = 0; j < 8; j++)
            vecCiphertext.push_back(tmp[j]);

        //重置ivec
        memcpy(ivec, outputText, 8);
    }

    if (clearText.length() % 8 != 0)
    {
        int tmp1 = clearText.length() / 8 * 8;
        int tmp2 = clearText.length() - tmp1;
        memset(inputText,(8-tmp2), 8);
        memcpy(inputText, clearText.c_str() + tmp1, tmp2);
    }
    else
    {
        memset(inputText,8, 8);
    }
    // 加密函数
    DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_ENCRYPT);  //加密

    memcpy(tmp, outputText, 8);

    for (int j = 0; j < 8; j++)
        vecCiphertext.push_back(tmp[j]);

    strCipherText.clear();
    strCipherText.assign(vecCiphertext.begin(), vecCiphertext.end());
    return strCipherText;
}

//解密 cbc pkcs5padding 本身实现  //zeropadding / pkcs7padding 跟 pkcs5padding是同样的SetLabel
std::string des_cbc_pkcs5_decrypt(const std::string &cipherText)
{
    static unsigned char cbc_iv[8] = {'t', 'c', 'l', 'd', 'i', 'g', 'i', 't'};
    //初始化IV向量
    std::string clearText;
    DES_cblock keyEncrypt, ivec;

    memcpy(keyEncrypt, cbc_iv, sizeof(cbc_iv));

    DES_key_schedule keySchedule;  //密钥表
    DES_set_key_unchecked(&keyEncrypt, &keySchedule);   //设置密钥，且不检测密钥奇偶性

    memcpy(ivec, cbc_iv, sizeof(cbc_iv));

    // 循环解密，每8字节一次
    const_DES_cblock inputText;
    DES_cblock outputText;
    std::vector<unsigned char> vecCleartext;
    unsigned char tmp[8];

    for (int i = 0; i < cipherText.length() / 8; i++)
    {
        memcpy(inputText, cipherText.c_str() + i * 8, 8);
        DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_DECRYPT);  //解密
        memcpy(tmp, outputText, 8);

        for (int j = 0; j < 8; j++)
            vecCleartext.push_back(tmp[j]);

        //重置ivec
        //memcpy(ivec, outputText, 8);  //解密过程不须要用前一块的结果做为下一块的IV
    }

    if (clearText.length() % 8 != 0)
    {
        int tmp1 = clearText.length() / 8 * 8;
        int tmp2 = clearText.length() - tmp1;
        memset(inputText,0, tmp2);
        memcpy(inputText, cipherText.c_str() + tmp1, tmp2);
        DES_ncbc_encrypt(inputText, outputText, tmp2, &keySchedule, &ivec, DES_DECRYPT);  //解密
        memcpy(tmp, outputText, tmp2);
        for (int j = 0; j < 8; j++)
            vecCleartext.push_back(tmp[j]);
    }
    clearText.clear();
    clearText.assign(vecCleartext.begin(), vecCleartext.end());
    return clearText;
}

// 加密后密文转hex
std::string StringToHex(const std::string& data)
{
    const std::string hex = "0123456789ABCDEF";
    std::stringstream ss;

    for (std::string::size_type i = 0; i < data.size(); ++i)
        ss << hex[(unsigned char)data[i] >> 4] << hex[(unsigned char)data[i] & 0xf];

    return ss.str();
}
